#ifndef UHM_DISCRETE_OPS_MESH_HXX_
#define UHM_DISCRETE_OPS_MESH_HXX_

#define UHM_DISCRETE_OPS_MESH_UNROLL 4


namespace uhm {
  // ** Op Element
  template<class T_> Int_ op_elt_separate_nodes(typename T_::Tnd_* me) {

    typename T_::_Data_ e = me->get_data();
    if (me->is_leaf()) {
      e->separate();
    } else {

      Int_ size =0;

      // Size of vector 
#pragma unroll(UHM_DISCRETE_OPS_MESH_UNROLL)
      for (Int_ i=0;i<me->get_n_children();++i) {
        typename T_::_Data_ c = me->get_child(i)->get_data();
        size += c->schur().get_size();
      }

      // Update me
      e->push_begin(size);
#pragma unroll(UHM_DISCRETE_OPS_MESH_UNROLL)
      for (Int_ i=0;i<me->get_n_children();++i) {
        typename T_::_Data_ c = me->get_child(i)->get_data();
        e->update(c);
      }
      e->push_end();    
      e->separate();

      // Set relation
#pragma unroll(UHM_DISCRETE_OPS_MESH_UNROLL)
      for (Int_ i=0;i<me->get_n_children();++i) {
        typename T_::_Data_ c = me->get_child(i)->get_data();
        c->relation().set(c, e);
      }
    }

    return true;
  }

  template<class T_> Int_ op_elt_clear(typename T_::Tnd_* me) {
    typename T_::_Data_ e = me->get_data();
    e->clear(me->is_leaf());
    return true;
  }

}

#endif
